<?php
require_once(dirname(__FILE__).'/resourcepage_item.php');
require_once(dirname(__FILE__).'/resourcepage_file.php');
require_once(dirname(__FILE__).'/module_resourcepage.php');

/**
 * Class that holds information about resources in a container that has been retrieved
 * from the database.
 *
 * @copyright &copy; 2006 The Open University
 * @author s.marshall@open.ac.uk
 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
 * @package resourcepage
 */
class resourcepage_container {

    /** Container ID */
    private $container;

    /** Basic data about container */
    private $hidden,$plugininfo,$containertype,$nextupdate,$title,$resourcepageid,$livedate,$removedate,$showto;

    /** Array of contents (either items or subcontainers) */
    private $things=array();

    /** Format used for date display */
    const DATEFORMAT='j M Y';

    /**
     * Construct with global config.
     */
    public function __construct() {
    }

    /**
     * @return int Number of children (items and subcontainers)
     */
    public function get_child_count() {
        return count($this->things);
    }

    /**
     * @param $index Desired index from 0..get_child_count()-1
     * @return object Child (resourcepage_container or resourcepage_item)
     */
    public function get_child($index) {
        return $this->things[$index];
    }

    private function init_fields(&$rs,$index) {
        $this->container=$rs->fields['container'.$index];
        if($index>1) {
            $this->hidden=$rs->fields['hidden'.($index-1)] ? true : false;
        } else {
            $this->hidden=false;
        }
        $this->plugininfo=$rs->fields['plugininfo'.$index];
        $this->containertype=$rs->fields['containertype'.$index];
        $this->nextupdate=$rs->fields['nextupdate'.$index];
        $this->title=$rs->fields['title'.$index];
        $this->resourcepageid=$rs->fields['resourcepageid'.$index];
        $this->livedate=$rs->fields['livedate'.$index];
        $this->removedate=$rs->fields['removedate'.$index];
        $this->showto=$rs->fields['showto'.$index];
    }

    /**
     * Constructs results from database resultset. Stops when it reaches a row that refers
     * to a different container, or EOF.
     * @param object &$rs ADODB result set that currently points to the first line of results
     *   for this container. This comes from the evil query in module_resourcepage
     *   get_container_items_array.
     */
    public function init_from_database(&$rs) {
        $this->init_fields($rs,1);

        // Store information about current 'nesting position' so that we
        // can create the tree.
        $nest1id=null;
        $nest2id=null;
        $nest1=null;
        $nest2=null;
        $currentitem=null;

        // Keep processing rows until there are no more, or they start
        // being about some different top-level container.
        while(!$rs->EOF && $rs->fields['container1']==$this->container) {

            // Check row type
            switch($rs->fields['rowtype']) {

            case '1: item':
                // Item row

                // Convert nesting into the object tree
                $level1=$rs->fields['container2'];
                $level2=$rs->fields['container3'];

                if($level1!=$nest1id) {
                    unset($nest2); $nest2id=null;
                    if($level1 > 0) {
                        $nest1id=$level1;
                        unset($nest1);
                        $nest1=new resourcepage_container();
                        $nest1->init_fields($rs,2);
                        // Add inside this
                        $this->things[] =& $nest1;
                    } else {
                        unset($nest1);
                        $nest1id=null;
                    }
                }
                if($level2!=$nest2id) {
                    if($level2 > 0) {
                        $nest2id=$level2;
                        unset($nest2);
                        $nest2=new resourcepage_container();
                        $nest2->init_fields($rs,3);
                        // Add inside nest1
                        $nest1->things[] =& $nest2;
                    } else {
                        unset($nest2);
                        $nest2id=null;
                    }
                }

                if($rs->fields['item']) {
                    // Set up new item
                    unset($currentitem);

                    // Add within appropriate container
                    if($nest2id) {
                        $currentitem=new resourcepage_item($nest2, $rs->fields);
                        $nest2->things[] =& $currentitem;
                    } else if($nest1id) {
                        $currentitem=new resourcepage_item($nest1, $rs->fields);
                        $nest1->things[] =& $currentitem;
                    } else {
                        $currentitem=new resourcepage_item($this, $rs->fields);
                        $this->things[] =& $currentitem;
                    }

                    // Set item hidden field
                    $currentitem->set_item_field_hidden();
                }

                break;
            case '2: flag':
                // Flag row from this item
                $currentitem->init_flag($rs->fields['flag'],$rs->fields['value']);
                break;
            case '3: baseflag':
                // Flag row from base item
                $currentitem->init_flag($rs->fields['flag'],$rs->fields['value'],true);
                break;
            case '4: file':
                // File row
                $currentitem->init_file(new resourcepage_file($rs->fields['filepath'],
                    $rs->fields['mimetype'],$rs->fields['size'],$rs->fields['basefile']));
                break;
            default:
                throw new Exception('Unexpected database row: '.$rs->fields['rowtype']);
            }

            $rs->MoveNext();
        }
    }
    
    /**
     * Checks whether this container is hidden from students for any reason.
     * Reasons are: 1) the hidden flag, 2) the date/time options, 
     * 3) SAMS showto, 4) if the section contains no visible items
     * @param $course
     * @return unknown_type
     */
    public function is_hidden_from_students($course) {
        global $CFG;
        
        if ($this->hidden) {
            return true;
        }

        $livetime = module_resourcepage::convert_date($course->startdate,$this->livedate);
        $beforelivedate = !is_null($this->livedate) && time() < $livetime;
        if ($beforelivedate) {
            // Before live date
            return true;
        }

        $removetime = module_resourcepage::convert_date($course->startdate,$this->removedate);
        $afterremovedate = !is_null($this->removedate) && time() >= $removetime;
        if ($afterremovedate) {
            // After remove date
            return true;
        }
        
        if (defined('AUTH_SAMS') && AUTH_SAMS == $CFG->auth && $this->showto) {
            if(!class_exists('SamsAuth') || !SamsAuth::$inst->match_authids($this->showto)) {
                return true;
            }
        }
        
        if ($this->are_children_hidden_from_students($course)) {
            // No visible children
            return true;
        }
        
        // Not hidden!
        return false;
    }

    /**
     * Displays as HTML.
     * @param object $course Object representing row from Moodle course table
     * @param object $cm Course module table row
     * @param boolean $editmode True when page is in edit mode (or edit item mode)
     * @param boolean $edititem Set to 'item' ID when page is in edit item mode, null otherwise
     * @param boolean $inner If true, this is an inner container rather than the first one
     * @param boolean $itemcontrols If false, items within the container cannot
     *   be edited/moved (even when they have edit permission)
     * @param boolean $showinfo If true, shows information about items
     * @param boolean $first [Not sure - think this probably means it's first
     *   on the page]
     * @param int $parent ID of parent container if there is one
     */
    public function display($course, $cm, $editmode=false, $edititem=null,
        $inner=false, $itemcontrols=true, $parent=null, $parentobj=null,
        $indeleted=false, $showinfo=false, $first=false) {

        global $CFG;
        $mrp = module_resourcepage::$inst;
        
        // If not in editmode, hidden containers don't show at all unless
        // you have showinfo
        $hidden = $this->is_hidden_from_students($course);
        if($hidden && !$showinfo && !$editmode) {
            return;
        }

        if ($editmode && !$inner) {
            // Find out if page is shared anywhere
            $rs=$mrp->do_sql("
SELECT DISTINCT
    rp.name AS pagename,c.shortname,c.fullname,cm.id
FROM
    prefix_resourcepage_containeritems ci
    INNER JOIN prefix_resourcepage_containers co ON ci.containerid=co.id
    INNER JOIN prefix_resourcepage rp ON co.resourcepageid=rp.id
    INNER JOIN prefix_course_modules cm ON cm.instance=rp.id
    INNER JOIN prefix_modules m ON cm.module=m.id
    INNER JOIN prefix_course c ON cm.course=c.id
WHERE
    ci.subcontainerid={$this->container}
    AND m.name='resourcepage'");

            // Display information as links
            if(!$rs->EOF) {
                print "
<div class='rp_sharedfrom'><strong>This is a shared page</strong>. Any changes also affect the following:
<ul>";
                while(!$rs->EOF) {
                    print "
<li>
  <a href='view.php?id={$rs->fields['id']}'>{$rs->fields['pagename']}</a>
  ({$rs->fields['shortname']} {$rs->fields['fullname']})
</li>
                            ";
                    $rs->MoveNext();
                }
                print '</div>';
            }
        }

        $editingcontainer = (!empty($edititem) && ($edititem == "c".$this->container));

        $tagclasses='';
        if($editmode && $inner) {
            $tagclasses = 'rp_container'.($this->hidden ? ' rp_hidden' : '');
        }
        // Add CSS classes
        if ($this->containertype=='_section') {
            $tagclasses=trim($tagclasses.' rp_section');
        }
        if ($first) {
            $tagclasses=trim($tagclasses.' rp_first');
        }
        if ($hidden) {
            $tagclasses = trim($tagclasses.' rp_hidden');
        }
        if ($editmode || $showinfo || !$hidden) {
            print "<div class='$tagclasses'>";
        }

        // Containers only display any html in editmode and not for the top-level
        if($editmode && $inner) {
            if($itemcontrols && !$edititem) {
                // Show controls
                $sesskey=sesskey();
                $draghandlealt=get_string('draghandle','resourcepage');
                $pixpath=$CFG->pixpath;
                $update=get_string('update');
                $deletealt=get_string('delete');
                $showhide=$this->hidden ? 'show' : 'hide';
                $showhidealt=get_string($showhide);
                print
                    "<div class='rp_controls'>".
                    "<div class='rp_draghandle' id='rp_draghandle_{$parent}_c{$this->container}'><img onmousedown='return false' ondragstart='return false' src='draghandle.png' alt='$draghandlealt' tabindex='0' /></div><div class='rp_stdicons'>";
                if(preg_match('/^pull_([a-z]+)$/',$this->containertype,$matches)) {
                    $pullextension=$matches[1];
                } else {
                    $pullextension='';
                }
                if($pullextension) {
                    print
                        "<a class='scrollpos' href='editextension.php?sesskey={$sesskey}&amp;id={$cm->id}&amp;extension={$pullextension}&amp;container={$this->container}&amp;mode=update'>".
                            "<img src='$pixpath/t/edit.gif' alt='$update' />".
                        "</a>";
                } else {
                    print
                        "<a class='scrollpos' href='view.php?id={$cm->id}&amp;item=c{$this->container}'>".
                            "<img src='$pixpath/t/edit.gif' alt='$update' />".
                        "</a>";
                }
                print
                        "<form method='post' action='containeritem.php'>".
                        "<input type='hidden' name='scrollpos' />".
                        "<input type='hidden' name='sesskey' value='$sesskey' />".
                        "<input type='hidden' name='id' value='$cm->id' />".
                        "<input type='hidden' name='container' value='$parent' />".
                        "<input type='hidden' name='item' value='c{$this->container}' />".
                        "<input type='hidden' name='extensiontype' value='{$pullextension}' />";
                if ($pullextension || $this->containertype == '_section') {
                    print
    "<input class='rp_img' name='actioncopy' type='image' src='$pixpath/t/copy.gif' alt='".get_string('copy','resourcepage')."' />";
                }
                print
                        "<input class='rp_img' name='action$showhide' type='image' src='$pixpath/t/$showhide.gif' alt='$showhidealt' />".
                        "<input class='rp_img' name='actiondelete' type='image' src='$pixpath/t/delete.gif' alt='$deletealt' />".
                        "</form>";
                if (!$indeleted) {
                    echo '<input class="rp_selectsection" type="checkbox" id="multiselect_'.$this->container.'" name="copyitems" value="'.$parent.'_s'.$this->container.'" onclick="checkBoxes(this, \'multiselect_\',document.getElementById(\'multi_idlist\'));" />';
                }
                echo "</div>";
                echo "</div>";

                // Stuff in containers can't be edited unless they're of _section type
                if($this->containertype!="_section") {
                    $itemcontrols=false;
                }
            }

            print '<div class="rp_mainbit">';
        } else if(!$editmode) {
        }

        // Section div and title, if applicable
        if ($this->containertype == '_section') {
            if (!empty($this->title)) {
                print '<h3 class="rp_sectionhead">' .
                    htmlspecialchars($this->title) .
                    '</h3> <div class="rp_section_content">';
            } else {
                print '<div class="rp_sectionnohead"></div><div class="rp_section_content">';
            }
        }

        // Check if editing container
        if ($editingcontainer) {
?>
<form class="rp_edititem" method="post" enctype="multipart/form-data" action="editcontainer.php" id="rp_editcontainerform" name="editcontainerform">
  <input type="hidden" name="sesskey" value="<?php print sesskey(); ?>" />
  <input type="hidden" name="id" value="<?php print $cm->id; ?>" />
  <input type="hidden" name="container" value="<?php print $this->container; ?>" />
  <input type="hidden" name="scrollpos" value="" />
  <input type="hidden" name="item" value="c" />
  <input type="hidden" name="actioncancel_x" value="1" />

  <h3><span class="rp_editlabel">
    <?php print get_string('editing_section', 'resourcepage'); ?>
  </span></h3>

  <div class="rp_label rp_label_text">
    <?php print get_string('field_title', 'resourcepage'); ?>
  </div>

  <div class="rp_field rp_field_text">
    <input type="text" name="title" value="<?php print htmlspecialchars($this->title); ?>" />
  </div>

<?php
            if ($this->containertype == '_section') {
?>

  <div class="rp_label rp_label_text">
    <?php print get_string('showto', 'resourcepage'); ?>
  </div>

  <div class="rp_field rp_field_text">
    <input type="text" name="showto" size="30" value="<?php print htmlspecialchars($this->showto); ?>" />
    <?php
    helpbutton('showto', get_string('help_showto', 'resourcepage'), 'resourcepage');
    ?>
    </div>
<?php
                // Do live/remove date
                $livedatestring = get_string('livedate', 'resourcepage');
                $livedatechecked = is_null($this->livedate) ? '' : 'checked="checked"';
                $removedatestring = get_string('removedate', 'resourcepage');
                $removedatechecked = is_null($this->removedate) ? '' : 'checked="checked"';
                print <<<HTMLEND
<script type="text/javascript" language="javascript">
    var livedateitems = ['livedateday','livedatemonth','livedateyear'];
    var removedateitems = ['removedateday','removedatemonth','removedateyear'];
</script>
<div class="rp_label">$livedatestring:</div>
<div class="rp_field">
    <input name="livedateenable" type="checkbox"
      onclick="return lockoptions('rp_editcontainerform', 'livedateenable', livedateitems)"
      $livedatechecked />
HTMLEND;
    
                $sign = $this->livedate < 0 ? '' : '+';
                $time = module_resourcepage::convert_date($course->startdate, $this->livedate);
                print_date_selector("livedateday", "livedatemonth", "livedateyear", $time);
                helpbutton('liveremovedate', get_string('livedate', 'resourcepage'), 'resourcepage');
    
                print <<<HTMLEND
</div>
<div class="rp_label">$removedatestring:</div>
<div class="rp_field">
    <input name="removedateenable" type="checkbox"
      onclick="return lockoptions('rp_editcontainerform', 'removedateenable', removedateitems)"
      $removedatechecked />
HTMLEND;
    
                $sign = $this->removedate < 0 ? '' : '+';
                $time = module_resourcepage::convert_date($course->startdate, $this->removedate);
                print_date_selector("removedateday", "removedatemonth", "removedateyear", $time);
                helpbutton('liveremovedate', get_string('removedate', 'resourcepage'), 'resourcepage');
    
                print '</div>';
    
                print '<script type="text/javascript">';
    
                if (!$livedatechecked) {
                    print "lockoptions('rp_editcontainerform', 'livedateenable', livedateitems);";
                }
                if (!$removedatechecked) {
                    print "lockoptions('rp_editcontainerform', 'removedateenable', removedateitems);";
                }
    
                print '</script>';
            }
?>

  <div class="rp_clear"></div>
  <div class="rp_savecancel">
  <input type="submit" value="Save changes" />
  <input type="button" value="Cancel" onclick="cancelcontaineredit()" />
  </div>
</form>
<?php
        }

        // Display child things
        for($i=0; $i<count($this->things); $i++) {

            // Drag target for moving
            if($editmode && !$edititem && $itemcontrols) {
                $this->display_drag_target($i+1,$parent);
            }

            // Child item
            $this->things[$i]->display($course, $cm, $editmode, $edititem,
                true, $itemcontrols, $this->container, $this, $indeleted,
                $showinfo, $i==0);
        }

        // If a page's owner is different to its parent, then it must be a shared
        // page - display information on where that page came from.
        if( $editmode && $inner && $parentobj->resourcepageid!=$this->resourcepageid) {
            // Get information about owner page and the course it comes from
            $rs=$mrp->do_sql("
SELECT
    rp.name AS pagename,c.shortname,c.fullname,cm.id
FROM
    prefix_course_modules AS cm
    INNER JOIN prefix_modules AS m ON cm.module=m.id
    INNER JOIN prefix_course AS c ON cm.course=c.id
    INNER JOIN prefix_resourcepage AS rp ON cm.instance=rp.id
WHERE
    cm.instance={$this->resourcepageid}
    AND m.name='resourcepage'
                    ");

            // Display information as a link
            if(!$rs->EOF) { // It should always exist but just in case
                print "
<div class='rp_shared'><strong>Shared content</strong> from
<a href='view.php?id={$rs->fields['id']}'>{$rs->fields['pagename']}</a>
({$rs->fields['shortname']} {$rs->fields['fullname']})</div>
                   ";
            }
        }

        // Final drag target
        if($editmode && !$edititem && $itemcontrols) {
            $this->display_drag_target(count($this->things)+1,$parent);
        }

        if($showinfo && $inner) {
            print '<div style="clear:both"></div>';
            // Display plugin info
            if($this->plugininfo) {
                print '<div class="rp_extra rp_contpi">'.
                    htmlspecialchars($this->plugininfo).'</div>';
            }
            
            // Display hidden marker
            if($this->hidden) {
                print '<div class="rp_extra rp_hidden">'.
                    get_string('adminmsg_hidden','resourcepage').'</div>';
            }
            
            // Display the authid if set
            if (!empty($this->showto) ) {
                print '<div class="rp_extra rp_hidden">' .
                    get_string('adminmsg_showsectionto', 'resourcepage',
                    $this->showto) . '</div>';
            }

            // Display the live date if set and not arrived yet
            $livetime = module_resourcepage::convert_date($course->startdate,$this->livedate);
            $beforelivedate = !is_null($this->livedate) && time() < $livetime;
            if ($beforelivedate) {
                print '<div class="rp_extra rp_hidden">' .
                    get_string('adminmsg_sectionbeforelivedate', 'resourcepage',
                    date(self::DATEFORMAT, $livetime)) . '</div>';
            }

            // Display the remove date if set
            $removetime = module_resourcepage::convert_date($course->startdate,$this->removedate);
            $afterremovedate = !is_null($this->removedate) && time() >= $removetime;
            if ($afterremovedate) {
                print '<div class="rp_extra rp_hidden">' .
                    get_string('adminmsg_sectionafterremovedate', 'resourcepage',
                    date(self::DATEFORMAT, $removetime)) . '</div>';
            } else if(!is_null($this->removedate)) {
                print '<div class="rp_extra rp_info">'.
                    get_string('adminmsg_removedatepresent', 'resourcepage',
                    date(self::DATEFORMAT, $removetime)).'</div>';
            }
        }

        if($editmode && !$inner) {
            ?>
<form action="moveitem.php" method="post" id="moveform"><div>
<input type="hidden" name="scrollpos" />
<input type="hidden" id="sourcecontainer" name="sourcecontainer" />
<input type="hidden" id="sourceitem" name="sourceitem" />
<input type="hidden" id="destcontainer" name="destcontainer" />
<input type="hidden" id="destindex" name="destindex" />
<input type="hidden" name="id" value="<?php print $cm->id ?>" />
<input type='hidden' name="sesskey" value="<?php print sesskey() ?>" />
</div></form>
            <?php
        }
        if($editmode && $inner) {
            print '</div>';
        }

        if ($editmode || !$this->hidden) {
            print '</div>';
        }

        if($this->containertype=='_section') {
            print '</div>';
        }
    }

    private function display_drag_target($index,$parent) {
        print
            '<div class="rp_dragtarget" id="rp_dragtarget_'.$this->container.'_'.$index.'_'.
            ($parent ? $parent : 'x').
            '"></div>';
    }

    public function get_container() {
        return $this->container;
    }
    public function get_resourcepage_id() {
        return $this->resourcepageid;
    }

    /**
     * Recursively searches for a container.
     * @param int $container Container ID
     * @return object The container in question, or null if not found
     */
    public function find_container($container) {
        if($this->container == $container) {
            return $this;
        }
        for($i=0;$i<count($this->things);$i++) {
            $thing=$this->things[$i];
            if(get_class($thing)=='resourcepage_container') {
                $return=$thing->find_container($container);
                if($return) {
                    return $return;
                }
            }
        }
        return null;
    }

    /**
     * Returns item with given ID. (Does not do recursive search.)
     * @param int $item Item ID.
     * @return object The item in question, or null if not present.
     */
    public function get_item($item) {
        for($i=0;$i<count($this->things);$i++) {
            $thing=$this->things[$i];
            if(get_class($thing)=='resourcepage_item') {
                if($thing->get_item() == $item) {
                    return $thing;
                }
            }
        }
        return null;
    }

    /**
     * Returns item with given ID. (Does do recursive search.)
     * @param int $item Item ID.
     * @return object The item in question, or null if not present.
     */
    public function get_item_recursive($item) {
        foreach ($this->things as $thing) {
            if (get_class($thing) == 'resourcepage_item') {
                if ($thing->get_item() == $item) {
                    return $thing;
                }
            } else if (get_class($thing) == 'resourcepage_container') {
                $found = $thing->get_item_recursive($item);
                if (!is_null($found)) {
                    return $found;
                }
            }
        }
        return null;
    }

    /**
     * Write backup XML for this container.
     * @param xml_backup &$backup Backup handler
     * @param module_resourcepage &$rp Resourcepage object
     * @param bool $sitefiles True to include site files
     */
    public function backup(&$backup,&$rp, &$mainrow, $sitefiles) {
        // Wanted to use CONTAINER here and ITEM for items but you can't do that
        // because the XML parser they use for restore groups things by tag name,
        // so you lose the ordering; so THING they are.
        $backup->tag_start('THING');
        $backup->tag_full('THINGTYPE','CONTAINER', false);

        // Check for Shared Section and set Container Type accordingly
        if ($this->containertype == '_page' && $this->resourcepageid != $mainrow->id) {
            $this->containertype = '_shared';
        }

        $backup->tag_full('CONTAINERTYPE',$this->containertype, false);
        $backup->tag_full_notnull('NEXTUPDATE',$this->nextupdate, false);
        $backup->tag_full_notnull('PLUGININFO',$this->plugininfo, false);
        $backup->tag_full_notnull('TITLE',$this->title, false);
        $backup->tag_full_notnull('RESOURCEPAGEID',$this->resourcepageid, false);
        $backup->tag_full_notnull('HIDDEN',$this->hidden, false);
        // 3 new fields added as per bug #4039
        $backup->tag_full_notnull('LIVEDATE',$this->livedate, false);
        $backup->tag_full_notnull('REMOVEDATE',$this->removedate, false);
        $backup->tag_full_notnull('SHOWTO',$this->showto, false);

        // Check for Shared [Resourcepage] Section
        if ($this->containertype == '_shared') {

            // Backup shared resourcepage name and sharing course shortname
            $backup->tag_full_notnull('SHAREDRESOURCEPAGENAME',get_field('resourcepage', 'name', 'id', $this->resourcepageid), false);
            $sharingcourseid = get_field('resourcepage', 'course', 'id', $this->resourcepageid);
            $backup->tag_full_notnull('SHARINGCOURSESHORTNAME',get_field('course', 'shortname', 'id', $sharingcourseid), false);
        } else {

            // If it's a pull extension container, back up its data too
            $matches=array();
            if(preg_match(module_resourcepage::CONTAINERTYPE_PULLEXTENSION,$this->containertype,$matches)) {
                $rp->get_specified_extension($matches[1])->backup($backup,$rp,$this->container);
            }

            // Do children
            foreach($this->things as $thing) {
                $thing->backup($backup,$rp, $mainrow, $sitefiles);
            }
        }
        $backup->tag_end('THING');
    }

    /**
     * Restore a container.
     * @param module_resourcepage $rp Owner resourcepage module
     * @param object $restoresettings Settings for restore
     * @param int $parentcontainerid ID of container's parent if it has one
     * @param array $xml Horrible-format XML array beginning with container's THING element
     * @param int $containerid ID of container if it has already been created, 0 otherwise
     */
    public static function restore($rp,$restoresettings,$parentcontainerid,$xml,$containerid=0) {
        $containertype=self::restore_get_field($xml,'CONTAINERTYPE');
        if($containerid==0) {

            // Check for Shared [Resourcepage] Section
            if ($containertype == '_shared') {

                // TODO can be removed when merge from moodle head after 20 Sep 2006
                if (empty($restoresettings->course_shortname)) {
                    $restoresettings->course_shortname = '';
                }

                // Shared [Resourcepage] Section, check if rolling course forward
                $sharingcourseshortname = self::restore_get_field($xml,'SHARINGCOURSESHORTNAME');

                // Check for updated shared resource page if rolling forward
                if (function_exists('update_sharing_shortname')) {
                    $prevcourseshortname = $restoresettings->course_shortname;
                    $currcourseshortname = get_field('course', 'shortname', 'id', $restoresettings->course_id);
                    $sharingcourseshortname = update_sharing_shortname($prevcourseshortname, $currcourseshortname, $sharingcourseshortname);
                }

                // Try and locate required resourcepage container id
                if (($sharingcourseid = get_field('course', 'id', 'shortname', $sharingcourseshortname)) &&
                    ($sharedcontainerid = get_field('resourcepage', 'containerid', 'course', $sharingcourseid, 'name', addslashes(self::restore_get_field($xml,'SHAREDRESOURCEPAGENAME')), 'shared', '1'))) {

                    // Found shared resourcepage container id so add to container items
                    $rp->add_container_subcontainer($parentcontainerid, $sharedcontainerid,
                        self::restore_get_field($xml,'HIDDEN') ? true : false);
                }
            } else {

                // Create and set up container - 3 new fields added as per bug
                $containerid=$rp->add_container(
                    $containertype,
                    $restoresettings->resourcepageid, // resourcepage id
                    self::restore_get_field($xml,'NEXTUPDATE'),
                    self::restore_get_field($xml,'PLUGININFO'),
                    self::restore_get_field($xml,'TITLE'),
                    self::restore_get_field($xml,'LIVEDATE'),
                    self::restore_get_field($xml,'REMOVEDATE'),
                    self::restore_get_field($xml,'SHOWTO'));
                // Assume $parentcontainerid is not set for resourcepage level container
                if ($parentcontainerid) {
                    $rp->add_container_subcontainer($parentcontainerid,$containerid,
                        self::restore_get_field($xml,'HIDDEN') ? true : false);
                }

                // Is it a pull extension? If so, restore any settings it might have
                $matches=array();
                if(preg_match(module_resourcepage::CONTAINERTYPE_PULLEXTENSION,$containertype,$matches)) {
                    $rp->get_specified_extension($matches[1])->restore($restoresettings,$rp,$containerid,$xml);
                }
            }
        } else {

            // Assume must be base _page or _deleted container for resource page
            // but check anyway. Consider reviewing backup/restore xml format
            if ($containertype == '_page' || $containertype == '_deleted') {
                $rp->upd_container($containerid, $containertype,
                                   self::restore_get_field($xml,'NEXTUPDATE'),
                                   self::restore_get_field($xml,'PLUGININFO'),
                                   self::restore_get_field($xml,'TITLE'));
            }
        }

        // Create items
        $items=isset($xml['THING']) ? $xml['THING'] : NULL;
        if(is_array($items)) {
            foreach($items as $item) {
                switch($item['#']['THINGTYPE'][0]['#']) {
                    case 'ITEM' :
                        resourcepage_item::restore($rp,$restoresettings,$containerid,$item['#']);
                        break;
                    case 'CONTAINER' :
                        resourcepage_container::restore($rp,$restoresettings,$containerid,$item['#']);
                        break;
                    default:
                        throw new Exception('Unexpected THINGTYPE');
                }
            }
        }
    }

    private static function restore_get_field($xml,$field,$exceptifinhere=false) {
        if(!array_key_exists($field,$xml) ||
            ($exceptifinhere && array_key_exists(strtolower($field),$exceptifinhere))) {
            return null;
        }
        return $xml[$field][0]['#'];
    }

   /**
     * Export as a RSS Feed.
     * @param object $course Object representing row from Moodle course table
     * @param object $cm Course module table row
     * @param boolean $editmode True when page is in edit mode (or edit item mode)
     * @param boolean $edititem Set to 'item' ID when page is in edit item mode, null otherwise
     * @param boolean $inner If true, this is an inner container rather than the first one
     * @param boolean $itemcontrols If false, items within the container cannot
     *   be edited/moved (even when they have edit permission)
     * @param int $parent ID of parent container if there is one
     */
     public function export_as_rss($course,$resourcepage, $cm, $container,  $editmode=false, $edititem=null,$inner=false,$itemcontrols=true,$parent=null,$parentobj=null) {
        global $CFG;

        $content = '';

        $content = '<?xml version="1.0" encoding="ISO-8859-1" ?>
            <?xml-stylesheet type="text/xsl" href="'.$CFG->wwwroot.'/mod/resourcepage/rss.xsl"?>
            <rss version="2.0"><channel>';

        $content = $content.'<title>'.$course->shortname.' '.$resourcepage->name.'</title>';

        // channel requires a description and link

        // i.e http://<server>/moodle/mod/resourcepage/view.php?id=999

        $url = htmlspecialchars($CFG->wwwroot.'/mod/resourcepage/view.php?id='.$cm->id);
        $content = $content.'<link>'.htmlspecialchars($url).'</link>';
        $content = $content.'<description>'.$course->shortname.' '.$resourcepage->name.'</description>';

        // Display child things
        for($i=0;$i<count($this->things);$i++) {

            $thing=$this->things[$i];

            $content = $content.$this->things[$i]->display_as_rss($course,$cm,$editmode,$edititem,true,$itemcontrols,$container,$this);

        }

        $content = $content.'</channel></rss>';

        return $content;

    }

    //ou-specific begins
    
    /**
     * Generates rss suitable for podcasting.
     *
     * @param object $course Object representing row from Moodle course table
     * @param object $resourcepage
     * @param object $cm Course module table row
     */

    public function export_as_podcastrss($course,$resourcepage,$cm){
    	global $CFG;
    	
    	$content = '<?xml version="1.0" encoding="ISO-8859-1" ?>
    	<?xml-stylesheet type="text/xsl" href="' . $CFG->wwwroot . '/mod/resourcepage/rss_podcast.xsl"?>
    	<rss xmlns:media="http://search.yahoo.com/mrss/" 
    		 xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" version="2.0"><channel>';
    	
    	$content .= '<title>'.$course->shortname.' '.$resourcepage->name.'</title>';
    	
    	$url = htmlspecialchars($CFG->wwwroot.'/mod/resourcepage/view.php?id='.$cm->id);
    	$img = $CFG->wwwroot."/mod/resourcepage/pix/ou_logo_podcast.jpg";	
		
    	$content .= '<link>'.htmlspecialchars($url).'</link>';
		$content .= '<description>'.$course->shortname.' '.$resourcepage->name.'</description>';
		$content .= '<image><url>' . $img . '</url>
					 <title>'.$course->shortname.' '.$resourcepage->name.'</title>
					 <link>'.htmlspecialchars($url).'</link></image>';
		$content .= '<ttl>1440</ttl>';
		$content .= '<copyright>(c) The Open University ' . Date('Y') .'</copyright>';
		$content .= '<itunes:summary>'.$course->shortname.' '.$resourcepage->name.'</itunes:summary>';
		$content .= '<itunes:author>The Open University</itunes:author>';
		$content .= '<itunes:image href="' . $img . '"/>';		
		$content .= '<itunes:explicit>no</itunes:explicit>';
		$content .= '<media:rating scheme="urn:simple">nonadult</media:rating>';  
		
		
		foreach($this->things as $thing){
			$files = $thing->get_files();

			if($files[0]->get_mime_type() == 'audio/mp3'){
				$content .= $thing->display_rss_podcast($course);
			}
		}
		
		$content .= '</channel></rss>';
		
		return $content;

    }	
	
    
    /**
     * displays podcast links on resourcepage
     *
     * @param object $resourcepage
     * @param object $cm Course module table row
     */
    
    public function display_podcast_console($cm,$resourcepage){
    	global $CFG;
    	
    	if(sizeof($this->things) == 0){
    		return;
    	}
    	
    	foreach($this->things as $thing){
            if (is_a($thing, 'resourcepage_item')) {
                $files = $thing->get_files();

                if(!isset($files[0]) || $files[0]->get_mime_type() != 'audio/mp3'){
                    return;
                }
            }
    	}
    	
    	$str_subscribe = get_string('subscribepodcast','resourcepage');
    	
    	$url = $CFG->wwwroot . '/mod/resourcepage/create_rss_feed.php?feedtype=podcastrss&amp;id='.$cm->id;
    	$url = str_replace('http://','',$url);
    	
    	echo <<<EOF
<div id="rp_podcast">{$str_subscribe}<br/>
	<a href="itpc://{$url}">iTunes</a> <a href="zune://subscribe/?{$resourcepage->name}={$url}">Zune</a> <a href="zcast://{$url}">ZENCast</a> <a href="http://{$url}">RSS</a>
</div>
EOF;
	
    }
    
    //ou-specific ends
    
    
    /**
     * Displays as RSS.
     * @param object $course Object representing row from Moodle course table
     * @param object $cm Course module table row
     * @param boolean $editmode True when page is in edit mode (or edit item mode)
     * @param boolean $edititem Set to 'item' ID when page is in edit item mode, null otherwise
     * @param boolean $inner If true, this is an inner container rather than the first one
     * @param boolean $itemcontrols If false, items within the container cannot
     *   be edited/moved (even when they have edit permission)
     * @param int $parent ID of parent container if there is one
     */
    public function display_as_rss($course,$cm,$editmode=false,$edititem=null,$inner=false,$itemcontrols=true,$parent=null,$parentobj=null) {

        $content = '';

        // Display child things
        for($i=0;$i<count($this->things);$i++) {

            $thing=$this->things[$i];

            // Child item
            $content = $content.$this->things[$i]->display_as_rss($course,$cm,$editmode,$edititem,true,$itemcontrols,$this->container,$this);

        }

        return $content;

    }

   /**
     * Export as a Atom Feed.
     * @param object $course Object representing row from Moodle course table
     * @param object $cm Course module table row
     * @param boolean $editmode True when page is in edit mode (or edit item mode)
     * @param boolean $edititem Set to 'item' ID when page is in edit item mode, null otherwise
     * @param boolean $inner If true, this is an inner container rather than the first one
     * @param boolean $itemcontrols If false, items within the container cannot
     *   be edited/moved (even when they have edit permission)
     * @param int $parent ID of parent container if there is one
     */
     public function export_as_atom($course,$cm, $container, $editmode=false, $edititem=null,$inner=false,$itemcontrols=true,$parent=null,$parentobj=null) {

        $content = '';

        global $CFG;
        $content = $content.'<?xml version="1.0" encoding="ISO-8859-1"?>
            <?xml-stylesheet type="text/xsl" href="'.$CFG->wwwroot.'/blocks/newsfeed/atom.xsl"?>
            <feed xmlns="http://www.w3.org/2005/Atom">';

        // print out empty title
        $content = $content.'<title/>';

        // Display child things
        for($i=0;$i<count($this->things);$i++) {

            $thing=$this->things[$i];

            $content = $content.$this->things[$i]->display_as_atom($course,$cm,$editmode,$edititem,true,$itemcontrols,$container,$this);

        }

        $content = $content.'</feed>';

        return $content;

    }

    /**
     * Displays as Atom.
     * @param object $course Object representing row from Moodle course table
     * @param object $cm Course module table row
     * @param boolean $editmode True when page is in edit mode (or edit item mode)
     * @param boolean $edititem Set to 'item' ID when page is in edit item mode, null otherwise
     * @param boolean $inner If true, this is an inner container rather than the first one
     * @param boolean $itemcontrols If false, items within the container cannot
     *   be edited/moved (even when they have edit permission)
     * @param int $parent ID of parent container if there is one
     */
    public function display_as_atom($course,$cm,$editmode=false,$edititem=null,$inner=false,$itemcontrols=true,$parent=null,$parentobj=null) {

    $content = '';

        // Display child things
        for($i=0;$i<count($this->things);$i++) {

                $thing=$this->things[$i];

                // if(get_class($thing)=='resourcepage_item') {

                //    printf("<br>thing is an item so display item as rss<br>");

                // } // endif

            // Child item
            $content = $content.$this->things[$i]->display_as_atom($course,$cm,$editmode,$edititem,true,$itemcontrols,$this->container,$this);

        }

        return $content;
    }

    public function are_children_hidden_from_students($course) {
        // Check if children are empty
        foreach($this->things as $thing) {
            if (!$thing->is_hidden_from_students($course)) {
                return false;
            }
        }
        return true;
    }

    /*
     * Get a property of the container. Bug 7255
     * @param string $name property name
     * @return mixed
     */
    public function get_property($name) {

        if(empty($this->$name)){
            return null;
        }

        return $this->$name;
    }

}
?>